{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Update IAM Roles and Policies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import boto3\n",
    "import sagemaker\n",
    "import time\n",
    "from time import gmtime, strftime\n",
    "\n",
    "sagemaker_session = sagemaker.Session()\n",
    "role = sagemaker.get_execution_role()\n",
    "bucket = sagemaker_session.default_bucket()\n",
    "region = boto3.Session().region_name\n",
    "\n",
    "from botocore.config import Config\n",
    "\n",
    "config = Config(retries={\"max_attempts\": 10, \"mode\": \"adaptive\"})\n",
    "\n",
    "iam = boto3.client(\"iam\", config=config)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get SageMaker Execution Role Name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "role_name = role.split(\"/\")[-1]\n",
    "\n",
    "print(\"Role name: {}\".format(role_name))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "setup_iam_roles_passed = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **Pre-Requisite:  SageMaker notebook instance ExecutionRole contains `AdministratorAccess` Policy.**\n",
    "_Note:  The permissions used here are for demonstration purposes only.  Please follow least-privilege security principals appropriate for your environment._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "admin = False\n",
    "\n",
    "post_policies = iam.list_attached_role_policies(RoleName=role_name)[\"AttachedPolicies\"]\n",
    "for post_policy in post_policies:\n",
    "    if post_policy[\"PolicyName\"] == \"AdministratorAccess\":\n",
    "        admin = True\n",
    "        setup_iam_roles_passed = True\n",
    "        print(\"[OK] You are all set up to continue with this workshop!\")\n",
    "        break\n",
    "\n",
    "if not admin:   \n",
    "        print(\"*************** [ERROR] SageMakerExecutionRole needs the AdministratorAccess policy attached. *****************\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **If you see an ERROR message ^^ above ^^, please attach the AdministratorAccess Policy to the SageMaker notebook instance ExecutionRole.**\n",
    "_Note:  The permissions used here are for demonstration purposes only.  Please follow least-privilege security principals appropriate for your environment._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# if not admin:\n",
    "#     pre_policies = iam.list_attached_role_policies(RoleName=role_name)[\"AttachedPolicies\"]\n",
    "\n",
    "#     required_policies = [\"IAMFullAccess\"]\n",
    "\n",
    "#     for pre_policy in pre_policies:\n",
    "#         for role_req in required_policies:\n",
    "#             if pre_policy[\"PolicyName\"] == role_req:\n",
    "#                 print(\"Attached: {}\".format(pre_policy[\"PolicyName\"]))\n",
    "#                 try:\n",
    "#                     required_policies.remove(pre_policy[\"PolicyName\"])\n",
    "#                 except:\n",
    "#                     pass\n",
    "\n",
    "#     if len(required_policies) > 0:\n",
    "#         print(\n",
    "#             \"*************** [ERROR] You need to attach the following policies in order to continue with this workshop *****************\\n\"\n",
    "#         )\n",
    "#         for required_policy in required_policies:\n",
    "#             print(\"Not Attached: {}\".format(required_policy))\n",
    "#     else:\n",
    "#         print(\"[OK] You are all set to continue with this notebook!\")\n",
    "# else:\n",
    "#     print(\"[OK] You are all set to continue with this notebook!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AdministratorAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonSageMakerFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"IAMFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonS3FullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"ComprehendFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonAthenaFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"SecretsManagerReadWrite\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonRedshiftFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonEC2ContainerRegistryFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AWSStepFunctionsFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonKinesisFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonKinesisFirehoseFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from botocore.exceptions import ClientError\n",
    "\n",
    "# try:\n",
    "#     policy = \"AmazonKinesisAnalyticsFullAccess\"\n",
    "#     response = iam.attach_role_policy(PolicyArn=\"arn:aws:iam::aws:policy/{}\".format(policy), RoleName=role_name)\n",
    "#     print(\"Policy {} has been succesfully attached to role: {}\".format(policy, role_name))\n",
    "# except ClientError as e:\n",
    "#     if e.response[\"Error\"][\"Code\"] == \"EntityAlreadyExists\":\n",
    "#         print(\"[OK] Policy is already attached.\")\n",
    "#     elif e.response[\"Error\"][\"Code\"] == \"LimitExceeded\":\n",
    "#         print(\"[OK]\")\n",
    "#     else:\n",
    "#         print(\"*************** [ERROR] {} *****************\".format(e))\n",
    "\n",
    "# time.sleep(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Final Check*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# role = iam.get_role(RoleName=role_name)\n",
    "post_policies = iam.list_attached_role_policies(RoleName=role_name)[\"AttachedPolicies\"]\n",
    "\n",
    "required_policies = [\n",
    "    \"AdministratorAccess\",\n",
    "#     \"SecretsManagerReadWrite\",\n",
    "#     \"IAMFullAccess\",\n",
    "#     \"AmazonS3FullAccess\",\n",
    "#     \"AmazonAthenaFullAccess\",\n",
    "#     \"ComprehendFullAccess\",\n",
    "#     \"AmazonEC2ContainerRegistryFullAccess\",\n",
    "#     \"AmazonRedshiftFullAccess\",\n",
    "#     \"AWSStepFunctionsFullAccess\",\n",
    "#     \"AmazonSageMakerFullAccess\",\n",
    "#     \"AmazonKinesisFullAccess\",\n",
    "#     \"AmazonKinesisFirehoseFullAccess\",\n",
    "#     \"AmazonKinesisAnalyticsFullAccess\",\n",
    "]\n",
    "\n",
    "admin = False\n",
    "\n",
    "for post_policy in post_policies:\n",
    "    if post_policy[\"PolicyName\"] == \"AdministratorAccess\":\n",
    "        admin = True\n",
    "        try:\n",
    "            required_policies.remove(post_policy[\"PolicyName\"])\n",
    "        except:\n",
    "            break\n",
    "    else:\n",
    "        try:\n",
    "            required_policies.remove(post_policy[\"PolicyName\"])\n",
    "        except:\n",
    "            pass\n",
    "\n",
    "if not admin and len(required_policies) > 0:\n",
    "    print(\"*************** [ERROR] RE-RUN THIS NOTEBOOK *****************\")\n",
    "    for required_policy in required_policies:\n",
    "        print(\"Not Attached: {}\".format(required_policy))\n",
    "else:\n",
    "    setup_iam_roles_passed = True\n",
    "    print(\"[OK] You are all set up to continue with this workshop!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%store setup_iam_roles_passed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%store"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Release Resources"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%html\n",
    "\n",
    "<p><b>Shutting down your kernel for this notebook to release resources.</b></p>\n",
    "<button class=\"sm-command-button\" data-commandlinker-command=\"kernelmenu:shutdown\" style=\"display:none;\">Shutdown Kernel</button>\n",
    "        \n",
    "<script>\n",
    "try {\n",
    "    els = document.getElementsByClassName(\"sm-command-button\");\n",
    "    els[0].click();\n",
    "}\n",
    "catch(err) {\n",
    "    // NoOp\n",
    "}    \n",
    "</script>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%javascript\n",
    "\n",
    "try {\n",
    "    Jupyter.notebook.save_checkpoint();\n",
    "    Jupyter.notebook.session.delete();\n",
    "}\n",
    "catch(err) {\n",
    "    // NoOp\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "instance_type": "ml.t3.medium",
  "kernelspec": {
   "display_name": "Python 3 (Data Science)",
   "language": "python",
   "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/datascience-1.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
